import axios from 'axios';
import cache from './cache';
import store, { STORE_KEY } from '@store';
import common from './common';
import { ElLoading, ElMessage } from 'element-plus';
import lodash from 'lodash';
import router from '../router';
var login_invald = false;

export const Http_Result = {
    SUCCESS: 200,
    AUTH_INVALID: 1004,
    AUTH_INVALID1: 1005,
    ERROR: -1,
    FAIL: -2,
};
const AUTH_ERROR = [Http_Result.AUTH_INVALID, Http_Result.AUTH_INVALID1];

const postBase = {
    // 请求的接口，在请求的时候，如axios.get(url,config);这里的url会覆盖掉config中的url
    url: '/post',
    // 请求方法同上
    method: 'post', // default
    // 请求头信息
    headers: {
        'Content-Type': 'multipart/form-data;charset-utf-8',
        'Access-Control-Allow-Origin': '*',
    },
    // 设置超时时间
    timeout: 500000,
    // `withCredentials` 表示跨域请求时是否需要使用凭证
    withCredentials: true, // default
    // 返回数据类型
    responseType: 'json', // default
};

const postBaseResponseText = { ...postBase, responseType: 'text' };

const postBaseJsontype = {
    ...postBase,
    headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        'Access-Control-Allow-Origin': '*',
    },
};

const postFile = {
    ...postBase,
    timeout: 1800000,
    // 请求头信息
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded;charset-utf-8',
        'Access-Control-Allow-Origin': '*',
        // 'Content-Type': 'multipart/form-data'
    },
};

const postResArraybuffer = {
    ...postBase,
    // 请求头信息
    headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        'Access-Control-Allow-Origin': '*',
    },
    // 返回数据类型
    responseType: 'arraybuffer',
};

export const setURL = (url, args) => {
    if (typeof url === 'undefined') {
        throw 'no url!';
    }
    if (!args) return url;
    for (var i = 0; i < args.length; i++) {
        if (url.indexOf('{?}') < 0) {
            break;
        }
        url = url.replace(/\{\?\}/, args[i] + '');
    }
    // 最后是否有/{?}
    if (url.lastIndexOf('/{?}') > -1) {
        url = url.substr(0, url.lastIndexOf('/{?}'));
    }
    return url;
};

/**
 * option {
    loading: boolean true 菊花， false， 没有菊花（ 相当于无声请求）
    loadingText: 请稍等...
    param: 作为post数据传过去，json对象或者字符串, 如果是字符串那么可能是body形式传过去，
    pathParam: 接口名称中可能会有参数 []从数组中传过来,
    headParam
    method: //默认POST,
    postType: '默认application/json', 'form': 'x-www-form-urlencoded', 
    responseType: 'blob'
    token: 测试用的token
  }
  返回 Promise
 */
let loading;
export const post = (url, tParam, option = {}) => {
    url = setURL(url, option.pathParam);
    let hasLoading = option.loading;
    if (hasLoading) {
        if (loading) {
            loading.close();
        }
        loading = ElLoading.service({
            lock: true,
            text: option.loadingText ? option.loadingText : '加载中...',
            target: option.loadingTarget ? option.loadingTarget : 'app',
        });
    }
    let postType = lodash.cloneDeep(postBaseJsontype);
    if (option.postType === 'form') {
        postType = lodash.cloneDeep(postBase);
    }
    if (option.postType === 'text') {
        postType = lodash.cloneDeep(postBaseResponseText);
    } else if (option.postType === 'file') {
        postType = lodash.cloneDeep(postFile);
    } else if (option.postType === 'arraybuffer') {
        postType = lodash.cloneDeep(postResArraybuffer);
    }
    postType.headers['Content-Security-Policy'] = 'upgrade-insecure-requests';

    const accessToken = cache.get(cache.key.ACCESS_TOKEN);
    if (accessToken) {
        postType.headers.Authorization = accessToken;
    }

    let method = option.method ? option.method : 'post';
    let tPostType = { ...postType };
    tPostType.method = method;

    if (option.token) {
        tPostType.headers.Authorization = option.token;
    }
    if (option.headParam) {
        for (let x in option.headParam) {
            tPostType.headers[x] = option.headParam[x];
        }
        if (!option.headParam.isToken) {
            delete tPostType.headers.Authorization;
        }
    }

    let param = tParam || {};
    if (tParam) {
        if (option.postType === 'form') {
            param = tParam;
            param = new FormData();
            for (let x in tParam) {
                param.append(x, tParam[x]);
            }
        } else {
            // param = sign(param)
        }
    }

    return new Promise((resolve, reject) => {
        let axiosMethod;
        if (option.responseType === 'blob') {
            let axiosParam = {
                method: method,
                url: url,
                responseType: 'blob',
                headers: tPostType.headers,
            };
            if (method === 'get') {
                axiosParam.params = param;
            } else {
                axiosParam.data = param;
            }
            axiosMethod = axios(axiosParam);
        } else {
            if (method == 'get') {
                axiosMethod = axios.get(url, {
                    params: param,
                    headers: tPostType.headers,
                });
            } else if (method == 'delete') {
                axiosMethod = axios.delete(url, {
                    data: param,
                    ...tPostType,
                });
            } else {
                axiosMethod = axios[method](url, param, tPostType);
            }
        }

        axiosMethod
            .then(response => {
                if (hasLoading) {
                    if (loading) {
                        loading.close();
                    }
                }
                response.data.list = response.data.list || [];
                if (response.data.resultCode == 8201) {
                    let timeOut = setTimeout(() => {
                        router.replace({ path: '/login' });
                        clearTimeout(timeOut);
                    }, 2000);
                }
                if (response.status === 200) {
                    if (option.responseType === 'blob') {
                        response.data = { code: 200, data: response.data };
                    }

                    response.data.success = response.data.resultCode === 8200;
                    if (response.data.success) {
                        response.data.code = 200;
                        resolve(response.data);
                    } else {
                        if (AUTH_ERROR.includes(response.data.resultCode)) {
                            if (login_invald) return;
                            login_invald = true;
                            setTimeout(() => {
                                login_invald = false;
                            }, 2000);
                            store.dispatch(STORE_KEY.A_CLEAR_TOKEN);
                            ElMessage.error(response.data.message);
                            setTimeout(() => {
                                common.toLogin();
                            }, 500);
                        } else {
                            // if (hasLoading) {
                            response.data.message && ElMessage.error(response.data.message);
                            // }
                        }
                        // response.data.message && ElMessage.error(response.data.message);
                        reject(response.data);
                    }
                } else {
                    if (hasLoading) {
                        ElMessage.error('系统开小差');
                    }
                    reject(response);
                }
            })
            .catch(error => {
                // console.log('err' + error);
                // let { message } = error;
                // if (message == 'Network Error') {
                //     message = '后端接口连接异常';
                // } else if (message.includes('timeout')) {
                //     message = '系统接口请求超时';
                // } else if (message.includes('Request failed with status code')) {
                //     message = '系统接口' + message.substr(message.length - 3) + '异常';
                // } else {
                //     message = '系统开小差';
                // }
                if (hasLoading) {
                    if (loading) {
                        loading.close();
                    }
                }
                if (option.responseType === 'blob' && error.response.data instanceof Blob) {
                    var reader = new FileReader();
                    reader.readAsText(error.response.data);
                    reader.onload = function (event) {
                        const { code, message } = JSON.parse(reader.result);
                        reject({ success: false, code, message });
                        if (hasLoading) {
                            ElMessage.error(message);
                        }
                    };
                    return;
                } else {
                    ElMessage.error('登录账户已失效,两秒后退出登录');
                    reject({ success: false, list: [] });
                    let timeOut = setTimeout(() => {
                        router.replace({ path: '/login' });
                        clearTimeout(timeOut);
                    }, 2000);
                }
                // if (AUTH_ERROR.includes(error.response.status)) {
                //     if (login_invald) return
                //     login_invald = true
                //     setTimeout(() => {
                //         login_invald = false
                //     }, 2000)
                //     store.dispatch(STORE_KEY.A_CLEAR_TOKEN)
                //     ElMessage.error('登录过期')
                //     setTimeout(() => {
                //         common.toLogin()
                //     }, 500)
                // } else {
                //     if (error.response && error.response.data) {
                //         const { code } = error.response.data
                //         !!error.response.data.message && (message = error.response.data.message)
                //         reject({ success: false, code, message })
                //     } else {
                //         reject(error || {})
                //     }
                //     if (hasLoading) {
                //         ElMessage.error(message)
                //     }
                // }
            });
    });
};

export const postL = (url, tParam, option = {}) => {
    return post(url, tParam, { ...option, loading: true });
};

export const get = (url, param, option = {}) => {
    option.method = 'get';
    return post(url, param, option);
};

export const getL = (url, param, option = {}) => {
    return get(url, param, { ...option, loading: true });
};

export const del = (url, param, option = {}) => {
    option.method = 'delete';
    return post(url, param, option);
};

export const delL = (url, param, option = {}) => {
    return del(url, param, { ...option, loading: true });
};

export const put = (url, param, option = {}) => {
    option.method = 'put';
    return post(url, param, option);
};

export const putL = (url, param, option = {}) => {
    return put(url, param, { ...option, loading: true });
};
